const express = require('express')
const cors = require('cors')
const jwt = require('jsonwebtoken')
const WebSocket = require('ws')
const wss = require('../services/websocket-server')
const {
  addUser,
  getUserById,
  getUserByName,
  loginUser,
  updateUser,
  deleteUser,
} = require('../services/userServices')
const {
  addReport,
  getReportById,
  getReport,
  updateReportStatus,
} = require('../services/roadConditionReportServices')
const {
  addNotice,
  getAllNotice,
} = require('../services/constructionNoticeServices')

const app = express()
const port = 3001
const secretKey = 'Learn_JWT_Secret_Key_2024@GuangGu#Traffic$Demo'

// 处理body中Json数据的中间件
app.use(express.json())
// 处理跨域请求的中间件
app.use(
  cors({
    origin: [
      'http://localhost:5173',
      'http://localhost:5174',
      'http://localhost:5175',
    ],
    methods: ['GET', 'POST', 'PUT', 'DELETE'], // 允许的 HTTP 方法
    allowedHeaders: ['Content-Type', 'Authorization'], // 允许的请求头
  })
)

// JWT 验证中间件
const verifyToken = (req, res, next) => {
  const authHeader = req.headers.authorization

  if (!authHeader?.startsWith('Bearer ')) {
    return res.status(401).json({
      message: '缺少授权令牌',
      error: 'Authorization header格式应为: Bearer <token>',
    })
  }

  const token = authHeader.split(' ')[1]

  jwt.verify(token, secretKey, (err, decoded) => {
    if (err) {
      return res.status(403).json({
        message: '无效或过期的令牌',
        error: err.message,
      })
    }
    req.user = decoded
    next()
  })
}

/* ---------- 用户相关接口 ---------- */
// 用户注册
app.post('/register', async (req, res) => {
  try {
    const { username, password } = req.body
    const result = await addUser({ username, password })
    if (result.status === 1) {
      // 广播用户更新消息
      wss.clients.forEach((client) => {
        if (client.readyState === WebSocket.OPEN) {
          client.send(JSON.stringify({ type: 'userUpdated' }))
        }
      })
      res.status(201).json({
        data: result,
        message: '注册成功',
      })
    }
  } catch (error) {
    if (error.message === 'USERNAME_EXISTS') {
      res.status(409).json({
        message: '用户名已存在',
        error: error.message,
      })
    } else {
      res.status(400).json({
        message: '请求参数错误',
        error: error.message,
      })
    }
  }
})

// 用户登录
app.post('/login', async (req, res) => {
  try {
    const { username, password } = req.body
    const result = await loginUser(username, password)
    if (result.status === 0) {
      return res.status(401).json({
        message: '登录失败',
        error: '用户名或密码错误',
      })
    }
    const token = jwt.sign({ username: result.data.username }, secretKey, {
      expiresIn: '1h',
    })
    // 广播用户更新消息
    wss.clients.forEach((client) => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(JSON.stringify({ type: 'userUpdated' }))
      }
    })
    res.status(200).json({
      data: result,
      token: token,
      message: '登录成功',
    })
  } catch (error) {
    res.status(500).json({
      message: '服务器错误',
      error: error.message,
    })
  }
})

// 更新用户信息
app.put('/updateuser', verifyToken, async (req, res) => {
  try {
    const { id, userObj } = req.body
    const result = await updateUser(id, userObj)
    if (result.status === 0) {
      return res.status(404).json({
        message: '更新用户失败',
        error: '用户不存在',
      })
    }
    // 广播用户更新消息
    wss.clients.forEach((client) => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(JSON.stringify({ type: 'userUpdated' }))
      }
    })
    res.status(200).json({
      data: result,
      message: '更新用户成功',
    })
  } catch (error) {
    if (error.message === 'USERNAME_EXISTS') {
      res.status(409).json({ message: '用户名已存在' })
    } else {
      res.status(500).json({ message: '服务器错误' })
    }
  }
})

// 删除用户
app.post('/deleteuser', verifyToken, async (req, res) => {
  try {
    const { id } = req.body
    const result = await deleteUser(id)
    if (result.status === 0) {
      return res.status(404).json({
        message: '删除用户失败',
        error: '用户不存在',
      })
    }
    // 广播用户更新消息
    wss.clients.forEach((client) => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(JSON.stringify({ type: 'userUpdated' }))
      }
    })
    res.status(204).json({
      message: '删除用户成功',
    })
  } catch (error) {
    res.status(500).json({
      message: '服务器错误',
      error: error.message,
    })
  }
})

// 新增用户（注意和注册用户区分）
app.post('/adduser', verifyToken, async (req, res) => {
  try {
    const { userObj } = req.body
    const result = await addUser(userObj)
    if (result.status === 1) {
      // 广播用户更新消息
      wss.clients.forEach((client) => {
        if (client.readyState === WebSocket.OPEN) {
          client.send(JSON.stringify({ type: 'userUpdated' }))
        }
      })
      res.status(201).json({
        message: '新增用户成功',
        data: result,
      })
    }
  } catch (error) {
    if (error.message === 'USERNAME_EXISTS') {
      res.status(409).json({
        message: '用户名已存在',
        error: error.message,
      })
    } else {
      res.status(400).json({
        message: '请求参数错误',
        error: error.message,
      })
    }
  }
})

// 根据id查询用户
app.post('/getuserbyid', async (req, res) => {
  try {
    const { id } = req.body
    const result = await getUserById(id)
    if (result.status === 0) {
      return res.status(404).json({
        message: '查询用户失败',
        error: '用户不存在',
      })
    }
    res.status(200).json({
      data: result,
      message: '查询用户成功',
    })
  } catch (error) {
    res.status(400).json({
      message: '查询用户失败',
      error: error.message,
    })
  }
})

// 根据用户名查询用户
app.post('/getuserbyname', async (req, res) => {
  try {
    const { username } = req.body
    const result = await getUserByName(username)
    if (result.status === 0) {
      return res.status(404).json({
        message: '查询用户失败',
        error: result.message,
      })
    }
    res.status(200).json({
      data: result,
      message: '查询用户成功',
    })
  } catch (error) {
    res.status(400).json({
      message: '查询用户失败',
      error: error.message,
    })
  }
})

/* ---------- 路况报告接口 ---------- */
// 新增路况报告
app.post('/addreport', verifyToken, async (req, res) => {
  try {
    const { reportObj } = req.body
    const result = await addReport(reportObj)
    if (result.status === 1) {
      res.status(201).json({
        message: '新增路况报告成功',
        data: result,
      })
    }
  } catch (error) {
    res.status(400).json({
      message: '新增路况报告失败',
      error: error.message,
    })
  }
})

// 根据id查询路况报告
app.post('/getreportbyid', async (req, res) => {
  try {
    const { id } = req.body
    const result = await getReportById(id)
    if (result.status === 0) {
      return res.status(404).json({
        message: '查询路况报告失败',
        error: '报告不存在',
      })
    }
    res.status(200).json({
      data: result,
      message: '查询路况报告成功',
    })
  } catch (error) {
    res.status(400).json({
      message: '查询路况报告失败',
      error: error.message,
    })
  }
})

// 模糊查询路况报告
app.post('/getreport', async (req, res) => {
  try {
    const { str } = req.body
    const result = await getReport(str)
    if (result.status === 0) {
      return res.status(404).json({
        message: '查询路况报告失败',
        error: '未找到相关报告',
      })
    }
    res.status(200).json({
      data: result,
      message: '查询路况报告成功',
    })
  } catch (error) {
    res.status(400).json({
      message: '查询路况报告失败',
      error: error.message,
    })
  }
})

// 根据id更新路况报告审核状态
app.post('/updatereportstatus', verifyToken, async (req, res) => {
  try {
    const { id, status } = req.body
    const result = await updateReportStatus(id, status)
    if (result.status === 0) {
      return res.status(404).json({
        message: '更新路况报告审核状态失败',
        error: '报告不存在',
      })
    }
    res.status(200).json({
      data: result,
      message: '更新路况报告审核状态成功',
    })
  } catch (error) {
    res.status(400).json({
      message: '更新路况报告审核状态失败',
      error: error.message,
    })
  }
})

/* ---------- 施工通告接口 ---------- */
// 新增施工公告
app.post('/addnotice', verifyToken, async (req, res) => {
  try {
    const { noticeObj } = req.body
    const result = await addNotice(noticeObj)
    if (result.status === 1) {
      res.status(201).json({
        message: '新增施工通告成功',
        data: result,
      })
    }
  } catch (error) {
    res.status(400).json({
      message: '新增施工通告失败',
      error: error.message,
    })
  }
})

// 查询所有施工公告
app.post('/getallnotice', async (req, res) => {
  try {
    const result = await getAllNotice()
    if (result.status === 0) {
      return res.status(404).json({
        message: '未找到施工公告数据',
        error: '未找到施工公告数据',
      })
    }
    res.status(200).json({
      data: result,
      message: '查询施工公告成功',
    })
  } catch (error) {
    res.status(400).json({
      message: '查询施工公告失败',
      error: error.message,
    })
  }
})

app.listen(port, () => {
  console.log(`服务器运行在端口 ${port}`)
})
